Skip to content

fix: tell a dead sensor apart from one with no data (#1102) - #1107

Open
MOHITKOURAV01 wants to merge 1 commit into
Aditya8369:mainfrom
MOHITKOURAV01:fix/1102-sensor-health-polling
Open

fix: tell a dead sensor apart from one with no data (#1102)#1107
MOHITKOURAV01 wants to merge 1 commit into
Aditya8369:mainfrom
MOHITKOURAV01:fix/1102-sensor-health-polling

Conversation

@MOHITKOURAV01

Copy link
Copy Markdown
Contributor

Closes #1102

sensor_health_scores.health_score is INTEGER CHECK (0..100) and uptime_percentage is DECIMAL(5,2). Zero is legal and meaningful in both — it is what a sensor that has dropped out looks like — and both were read through ||, which cannot tell zero from absent.

The uptime tile was the bad one. metrics?.uptimePercentage || '98.5' rendered a specific, plausible, reassuring figure in the same blue as a healthy sensor, under a heading reading "Uptime (30 Days)", for both a genuine 0.00% and a missing field. Nothing on screen distinguished it from a measurement.

What changed

src/components/SensorHealthDashboard.jsx — three small exported helpers do the reading:

before after
score of 0 -- (reads as "no data") 0, coloured red
score absent -- in red -- in grey
uptime 0.00 98.5% 0%
uptime absent 98.5% No data, greyed

src/hooks/useSensorHealth.jsloadData set setLoading(true) on every 30-second poll, and the dashboard early-returns on loading. So twice a minute the whole component unmounted, taking the open "Acknowledge Alert" modal and the resolution notes typed into it with it. Writing a paragraph of maintenance notes was a race against a timer, and losing it gave no warning. loading is now the first load only; a refresh sets refreshing and updates in place.

setError(null) appeared nowhere, so one dropped request pinned the dashboard to a red message for the life of the page while the interval carried on succeeding invisibly behind the early return. It is now cleared by the next successful read, rendered as a banner over existing data rather than instead of it, and carries a retry.

Dropped the optimistic healthScore + 10 on acknowledge. Acknowledging records that a human saw an alert; it does not repair the sensor, the server is never asked to re-evaluate, and the next poll took the invented recovery straight back off again. Acknowledge three in a row and the dashboard claimed a 30-point recovery that never happened.

Also added: a request-id guard so a slow response for the previously selected sensor cannot paint over the current one, a mounted guard, and window.alert replaced by the in-page error banner.

Tests

23 new tests in src/components/SensorHealthDashboard.test.jsx, covering the helpers directly and the three behaviours above through the component — including one that types notes into the modal, advances the clock past the poll interval, and asserts the text is still there.

Verification

npx vitest run src/components/SensorHealthDashboard.test.jsx   # 23 passed
npx eslint src/hooks/useSensorHealth.js src/components/SensorHealthDashboard.jsx src/components/SensorHealthDashboard.test.jsx   # clean

Note: npm run build currently fails on main for two unrelated reasons — a duplicate nextLevel declaration in Leaderboard.jsx and framer-motion missing from package.json. Both are raised separately; neither is touched by this branch.

The health tiles both read through `||`, so zero and absent collapsed into
the same branch. `health_score` is `INTEGER CHECK (0..100)` and
`uptime_percentage` is `DECIMAL(5,2)` — zero is legal in both, and it is
what a sensor that has dropped out looks like. A sensor at 0% uptime
rendered `98.5%` in the same blue as a healthy one, under a heading
reading "Uptime (30 Days)". `98.5` is not a placeholder anyone can
recognise as a placeholder.

readMetric/formatPercentage/getScoreColor now keep the two apart: a real
zero renders as zero and colours red, a missing value renders "No data"
in grey.

The hook also set `loading` on every 30-second poll, and the dashboard
early-returns on `loading` — so twice a minute the whole page unmounted,
taking the open acknowledgment modal and the resolution notes typed into
it with it. `loading` is now the first load only; a refresh sets
`refreshing` and updates in place.

`error` never got cleared, so one dropped request pinned the dashboard to
a red message for the life of the page while the interval carried on
succeeding invisibly behind it. It is cleared by the next successful
read, shown as a banner over existing data rather than instead of it, and
offers a retry.

Dropped the optimistic `healthScore + 10` on acknowledge. Acknowledging
records that a human saw an alert; it does not repair the sensor, and the
next poll took the invented recovery straight back off again.
@vercel

vercel Bot commented Aug 28, 2026

Copy link
Copy Markdown

@MOHITKOURAV01 is attempting to deploy a commit to the Aditya Mahajan's projects Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions

Copy link
Copy Markdown

Thank You for Your Contribution! 🎉

Hi @MOHITKOURAV01,

Thank you for opening this Pull Request and contributing to our project. We truly appreciate your efforts.

Please make sure that:

  • Your code follows the project's guidelines.
  • You have linked the appropriate issue (if applicable).
  • Screenshots are added for UI/UX changes.
  • Your PR is ready for review.

The maintainer @Aditya8369 will review your PR shortly!

Happy Contributing! 🚀

@github-actions github-actions Bot added the ECSoC26 Contributions considered under ECSoC'26 label Aug 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ECSoC26 Contributions considered under ECSoC'26

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Sensor health dashboard reports a dead sensor as 98.5% uptime, and its 30-second poll discards the acknowledgment notes you are typing

1 participant